/**
 * Created by wust on 2019-10-28 09:34:36
 * Copyright © 2019 wust. All rights reserved.
 */
package com.sc.admin.core.api.open.user;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sc.admin.core.service.SysMenuService;
import com.sc.admin.core.service.SysResourceService;
import com.sc.common.dto.WebResponseDto;
import com.sc.common.entity.admin.account.SysAccount;
import com.sc.common.entity.admin.menu.SysMenu;
import com.sc.common.entity.admin.resource.SysResource;
import com.sc.common.entity.admin.user.SysUser;
import com.sc.common.enums.ApplicationEnum;
import com.sc.common.enums.RedisKeyEnum;
import com.sc.common.util.CommonUtil;
import com.sc.common.util.cache.SpringRedisTools;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author: wust
 * @date: Created in 2019-10-28 09:34:36
 * @description: 登录基类
 *
 */
public abstract class WebUserLoginBase {

    protected abstract SpringRedisTools getSpringRedisTools();

    protected abstract SysMenuService getSysMenuServiceImpl();

    protected abstract SysResourceService getSysResourceServiceImpl();

    protected abstract WebResponseDto validateAndGetUser(String loginName, String password, String code, String message, String checkCodeRC4);

    protected String[] createToken(String loginName) {
        return CommonUtil.generateWebToken(loginName);
    }


   /* protected abstract void before(JSONObject jsonObject);
    protected abstract void doLogin(JSONObject jsonObject);
    protected abstract void after(JSONObject jsonObject);

    @OperationLog(moduleName= OperationLogEnum.MODULE_COMMON,businessName="Web登陆：租户通过账号密码登陆",operationType= OperationLogEnum.Login)
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    protected ResponseDto login(@RequestParam("loginName") String loginName, @RequestParam("password") String password, @RequestParam("lang") String lang){
        ResponseDto responseDto = new ResponseDto();
        JSONObject jsonObject = new JSONObject();
        try{
            before(jsonObject);
            doLogin(jsonObject);
        }catch (Exception e){
            responseDto.setFlag(ResponseDto.INFO_WARNING);
            responseDto.setMessage("服务器异常");
        }finally {
            after(jsonObject);
        }
        return responseDto;
    }*/


    /**
     * 将当前用户拥有的菜单资源绑定到当前上下文
     * @param mapValue
     * @param accountId
     * @param accountType
     * @param permissionType
     * @param lang
     */
    protected void appendMenuToUserContext(final Map<String,Object> mapValue, Long accountId, String accountType,String permissionType, String lang){
        List<SysMenu> oneLevelMenus = null;                    // 非白名单一级菜单
        List<SysResource> resources = null;                    // 非白名单资源
        List<SysResource> resources4anon = null;               // 白名单资源

        if(CommonUtil.isSuperAdminAccount(accountType)){ // 平台超级管理员
            oneLevelMenus = getSysMenuServiceImpl().findOneLevelMenus4superAdmin(permissionType,lang.replace("-","_"));
            resources = getSysResourceServiceImpl().findAllResources4superAdmin(permissionType,lang.replace("-","_"));
            resources4anon = getSysResourceServiceImpl().findAllAnonResources4superAdmin(permissionType,lang.replace("-","_"));
        }else if(CommonUtil.isAdminAccount(accountType)){ // 平台普通管理员
            oneLevelMenus = getSysMenuServiceImpl().findOneLevelMenus4admin(permissionType,lang.replace("-","_"),accountId);
            resources = getSysResourceServiceImpl().findResources4admin(permissionType,lang.replace("-","_"),accountId);
            resources4anon = getSysResourceServiceImpl().findAnonResources4admin(permissionType,lang.replace("-","_"),accountId);
        }else{ // 员工
            oneLevelMenus = getSysMenuServiceImpl().findOneLevelMenusByUserId(permissionType,lang.replace("-","_"),accountId);
            resources = getSysResourceServiceImpl().findResourcesByUserId(permissionType,lang.replace("-","_"),accountId);
            resources4anon = getSysResourceServiceImpl().findAnonResourcesByUserId(permissionType,lang.replace("-","_"),accountId);
        }

        mapValue.put("oneLevelMenus",oneLevelMenus);
        mapValue.put("resources",resources);
        mapValue.put("anonResources",resources4anon);
    }


    /**
     * 将当前用户拥有的所有【菜单名称与url映射】绑定到当前上下文
     * @param mapValue
     * @param permissionType
     * @param lang
     */
    protected void appendMenuNameToUserContext(final Map<String,Object> mapValue, String permissionType,String lang){
        List<SysMenu> menus = getSysMenuServiceImpl().findMenuNameByPermissionType(permissionType,lang.replace("-","_"));
        JSONArray jsonArray = new JSONArray(menus.size());
        if(CollectionUtils.isNotEmpty(menus)){
            for (SysMenu menu : menus) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("name",menu.getName());
                jsonObject.put("description",menu.getDescription());
                jsonObject.put("url",menu.getUrl());
                jsonArray.add(jsonObject);
            }
        }
        mapValue.put("menuNames",jsonArray);
    }


    protected void appendAccountToUserContext(final Map<String,Object> mapValue,final SysAccount account){
        mapValue.put("account",account);
    }


    protected void appendUserToUserContext(final Map<String,Object> mapValue,final SysUser user){
        mapValue.put("user",user);
    }


    /**
     * 将当前用户拥有的项目列表绑定到当前上下文
     * @param mapValue
     * @param userId
     */
    protected void appendProjectToUserContext(final Map<String,Object> mapValue,Long userId){
        JSONArray sysProjects = new JSONArray();
        String key = String.format(RedisKeyEnum.REDIS_KEY_HASH_GROUP_PROJECT_BY_USER_ID.getStringValue(),userId);
        Map map = getSpringRedisTools().getMap(key);
        if(CollectionUtil.isNotEmpty(map)) {
            Set<Map.Entry<Long, Map>> entrySet = map.entrySet();
            for (Map.Entry<Long, Map> longMapEntry : entrySet) {
                Map projectMap = longMapEntry.getValue();
                if(!sysProjects.contains(JSONObject.toJSON(projectMap))){
                    sysProjects.add(JSONObject.toJSON(projectMap));
                }
            }
        }
        mapValue.put("myProjectList",sysProjects);
    }


    /**
     * 将当前语言环境绑定到当前上下文
     * @param mapValue
     * @param lang
     */
    protected void appendLangToUserContext(final Map<String,Object> mapValue,String lang){
        mapValue.put(ApplicationEnum.X_LOCALE.getStringValue(),lang);
    }

    /**
     * 将当前登录token绑定到当前上下文
     * @param mapValue
     * @param token
     */
    protected void appendTokenToUserContext(final Map<String,Object> mapValue,String token){
        mapValue.put(ApplicationEnum.X_AUTH_TOKEN.getStringValue(),token);
    }

    /**
     * 获取响应到前端的资源
     * @param accountType
     * @param mapValue
     * @return
     */
    protected JSONObject getResponseResource(String accountType,String permissionType,final Map<String,Object> mapValue){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("xAuthToken",mapValue.get(ApplicationEnum.X_AUTH_TOKEN.getStringValue()));
        jsonObject.put("accountId",null);
        jsonObject.put("loginName",null);
        jsonObject.put("realName",null);
        jsonObject.put("userType",permissionType);
        jsonObject.put("accountType",accountType);
        jsonObject.put("myProjectList",null);
        jsonObject.put("oneLevelMenus",mapValue.get("oneLevelMenus"));
        jsonObject.put("menuNames",mapValue.get("menuNames"));
        jsonObject.put("permissions",null);

        if("A101701".equals(accountType)) { // 系统管理员
            SysAccount account = (SysAccount)mapValue.get("account");
            jsonObject.put("accountId",account.getId());
            jsonObject.put("loginName",account.getAccountCode());
            jsonObject.put("realName",account.getAccountName());
        }else if("A101703".equals(accountType)){ // 员工
            jsonObject.put("accountId",((SysUser)mapValue.get("user")).getId());
            jsonObject.put("loginName",((SysUser)mapValue.get("user")).getLoginName());
            jsonObject.put("realName",((SysUser)mapValue.get("user")).getRealName());
            jsonObject.put("myProjectList",mapValue.get("myProjectList"));
        }

        /**
         * 简化并设置登录用户拥有的所有资源权限
         */
        if(mapValue.containsKey("resources") && mapValue.get("resources") != null){
            List<SysResource> permissions = (List<SysResource>)mapValue.get("resources");
            List<String> simplePermissions = new ArrayList<>(permissions.size());
            for (SysResource permission : permissions) {
                simplePermissions.add(permission.getPermission());
            }
            jsonObject.put("permissions",simplePermissions);
        }
        return jsonObject;
    }
}
